/*************************************************
*created by anchengan in 2024years 08months 05days
*This program is used to receive message from other
*program about autoai for user to use
*************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <unistd.h>
#include <signal.h>
#include "global_var.h"
#include "utils.h"
#define BUFFER_SIZE_1024 1024
#define BUFFER_SIZE_20 20
void handle_exit_sigint(int sig){
    close(server_fd);
    printf("autoai_master exit,return 0\n");
    exit(0);
}

void removeSubstring(char *source ,const char *substr){
    char *match;
    int len=strlen(substr);
    while ((match=strstr(source,substr))!=NULL){
        *match = '\0';
	strcat(source,match+len);
    }
}

int main(int argc,char *argv[]){
    char *ip = argv[1];
    char *port = argv[2];
    printf("This program is used to receive message from other program about autoai for user to use\n");
    printf("autoai_master IP address:%s\n",ip);
    printf("autoai_master port number:%s\n",port);
    printf("autoai_master setting up......\n");
    signal(SIGINT,handle_exit_sigint);
    int new_socket;
    struct sockaddr_in address;
    int opt =1;
    int addrlen=sizeof(address);
    proj_node* proj_record=NULL;
    char buffer[BUFFER_SIZE_1024]={0};
    char ret_msg[BUFFER_SIZE_1024]={0};
    char read_proj_name[BUFFER_SIZE_1024]={0};
    char read_proj_ip[BUFFER_SIZE_20]={0};
    char read_proj_port[BUFFER_SIZE_20]={0};
    int read_size;
    //create socket
    if((server_fd = socket(AF_INET,SOCK_STREAM,0))==0){
        perror("socket server established failed");
	exit(EXIT_FAILURE);
    }
    if (setsockopt(server_fd,SOL_SOCKET,SO_REUSEADDR | SO_REUSEPORT,&opt,sizeof(opt))){
        perror("socket port set failed");
	exit(EXIT_FAILURE);
    }
    address.sin_family=AF_INET;
    address.sin_addr.s_addr=inet_addr(ip);
    address.sin_port=htons(atoi(port));
    if(bind(server_fd,(struct sockaddr *)&address,sizeof(address))<0){
        perror("bind failed\n");
        exit(EXIT_FAILURE);
    }
    printf("autoai_master is listening on %s:%s......\n",ip,port);
    fd_set readfds;  
    struct timeval timeout;  
    int retval;  
     
    FD_ZERO(&readfds);  
    FD_SET(server_fd, &readfds);  
     
      
    timeout.tv_sec = 2;  
    timeout.tv_usec = 0; 
      
    
    while(1){
        if(listen(server_fd,3)<0){
	    perror("listen failed");
	    exit(EXIT_FAILURE);
	}	      
        FD_ZERO(&readfds);
        FD_SET(server_fd, &readfds);
	timeout.tv_sec = 2;
	timeout.tv_usec = 0;
	retval = select(server_fd + 1, &readfds, NULL, NULL, &timeout);  
        if (retval == -1) {  
            perror("select()");  
            // 处理错误  
        } else if (retval) {  
            // 检测到有连接请求  
            if (FD_ISSET(server_fd, &readfds)) {  
                struct sockaddr_in address;  
                socklen_t addrlen = sizeof(address);  
                int new_socket = accept(server_fd, (struct sockaddr *)&address, &addrlen);  
                if (new_socket == -1) {  
                    perror("accept()");  
                // 处理错误  
                } else {  
                // 处理新的连接  
                }  
            }  
        } else {  
            // 超时没有连接请求  
	    printf("Listening...\n");
            //printf("Timeout occurred! No connection requests.\n");  
        }	
	strcpy(buffer,"");
        read_size=recv(new_socket,buffer,BUFFER_SIZE_1024,0);
	buffer[read_size]='\0';
        if(strstr(buffer,"autoai_start")!=NULL){
	    removeSubstring(buffer,"autoai_start");
            printf("start:%s\n",buffer);
	    strcpy(ret_msg,"start_ok");
	}else if(strstr(buffer,"autoai_ipportset")!=NULL){
            removeSubstring(buffer,"autoai_ipportset");
            if(sscanf(buffer,"%[^-]-%[^:]:%s",read_proj_name,read_proj_ip,read_proj_port)==3){
		proj_node* temp_status=proj_record;
		while(temp_status!=NULL){
		    if(strcmp(temp_status->str,read_proj_name)==0){
                        temp_status->status=6;
			break;
		    }
                    temp_status=temp_status->next;
		}
		proj_node* temp = proj_record;
		while(temp!=NULL){
		    if(strcmp(temp->str,read_proj_name)==0){
		        break;
		    }
		    temp=temp->next;
		}
		if(temp==NULL){
		    appendprojnode(&proj_record,read_proj_name,read_proj_ip,read_proj_port);
		    printf("Set project %s IP:%s PORT:%s\n",read_proj_name,read_proj_ip,read_proj_port);
		}
                
                strcpy(ret_msg,"service_set_ok!");
	    }else{
                printf("Fail to parse IP and PORT\n");
		strcpy(ret_msg,"service_set_failed");
	    }
        }
	send(new_socket,ret_msg,strlen(ret_msg),0);
        close(new_socket);
	proj_node* temp	= proj_record;
        int del_status=0;
	char del_str[100];
	while(temp!=NULL){
	    
	    temp->status--;
	    if(temp->status<=0){
		strcpy(del_str,temp->str);
		del_status=1;
		break;
	    }
	    
	    temp=temp->next;
	    
	}
	if (del_status==1){
	    deleteprojnode(&proj_record,del_str);
            printf("Project %s have been stopped!\n",del_str);
	}
	
    }
    return 0;
}
